## @package karboom.layers
# Extended layers
#
# Extensions of the karboom.classes.Layer
#

from karboom import errors

from karboom.classes import Layer, Base
from karboom.paths import TextPath

import cairo

## Path layer
#
# Path rendering
#
class PathLayer(Layer):
    
    ## Mode to use (stroke or fill)
    mode = 'fill'
    
    ## Path to use
    path = None
    
    def __render__(self):
        Layer.__render__(self)
        
        self.path.context = self.context
        self.path.__render__()
        
        if self.mode.split(':')[0] == 'fill':
            self.context.fill()
        elif self.mode.split(':')[0] == 'stroke':
            try:
                self.context.set_line_width(float(self.mode.split(':')[1]))
            except IndexError:
                raise errors.LayerError('Width for stroke not specified')
            except ValueError:
                raise errors.LayerError('Width for stroke invalid')
            self.context.stroke()
        else:
            raise errors.LayerError('PathLayer mode is not set to fill or stroke')
        
        Layer.__finishrender__(self)
        
## Text layer
#
# Basic path-based text rendering
#
class TextLayer(PathLayer):
    
    ## Text to render
    text = ''
    
    ## Font to use
    font = None
    
    ## Font size to use
    fontsize = 0
    
    ## Get the TextPath for the text
    def __path__(self):
        return TextPath(text=self.text, font=self.font, fontsize=self.fontsize)
    
    def __render__(self):
        self.path = self.__path__()
        PathLayer.__render__(self)
    
## SVG layer
#TODO: Implement!
#
# Render SVG images
#
class SVGLayer(Layer):
    
    ## SVG data
    data = None
    
    def __init__(self, **kwargs):
        raise errors.UnimplementedError('VectorLayer is not implemented')
        
## Raster layer
#TODO: Check if it works.
#
# Render raster images
#
class RasterLayer(Layer):
    
    ## Image size, in a 2-tuple formatted (width, height)
    imgsize = (0, 0)
    
    ## raster image data
    data = None
    
    ## Convert a PathLayer to a RasterLayer
    #TODO: Check if it works.
    #
    # @param pathlayer: PathLayer to convert
    @staticmethod
    def from_pathlayer(pathlayer):
        pathlayer.__render__()
        vecsurf = pathlayer.context.get_target()
        self.data = vecsurf.get_data()
        self.imgsize = (vecsurf.get_width(), vecsurf.get_height())
        pathlayer.context.save()
        pathlayer.context.set_source_rgba(0, 0, 0, 0)
        pathlayer.context.set_operator(cairo.OPERATOR_SOURCE)
        pathlayer.context.paint()
        pathlayer.context.restore()
    
    def __render__(self):
        Layer.__render__(self)
        self.context.set_source(cairo.SurfacePattern(cairo.ImageSurface.create_for_data(
                                                                                        self.data,
                                                                                        cairo.FORMAT_ARGB32,
                                                                                        self.imgsize[0],
                                                                                        self.imgsize[1]
                                                                                        )))
        self.context.rectangle(0, 0, self.imgsize[0], self.imgsize[1])
        Layer.__finishrender__(self)

## PNG Layer
#TODO: Check if it works.
#
# Render PNG images
#
class PNGLayer(RasterLayer):
    
    ## PNG data
    data = None
    
    def __render__(self):
        pngsurf = cairo.ImageSurface.create_from_png(self.data)
        RasterLayer(imgsize=(get_width(), get_height()), data=pngsurf.get_data()).__render__(self)